import time
import threading

from yysautomatic.setting import locate_interval
from yysautomatic.log import get_logger
from .gui import gui
from .component import Component
from .event import EventManager, EventType

logger = get_logger(__name__)


class Frame(Component, threading.Thread):
    """
    游戏主窗口
    """

    def __init__(self, win_id, title=None):
        super().__init__()
        threading.Thread.__init__(self)
        self.__stop_flag = False
        self.__win_id = win_id
        self.__title = title
        self.__event_manager = EventManager(self)

    @property
    def win_id(self):
        return self.__win_id

    def run(self):
        while not self.__stop_flag:
            self.__locate_sources()
            time.sleep(locate_interval / 1000)

    def destroy(self):
        self.__stop_flag = True

    def __locate_sources(self):
        # 判断窗口大小是否变动，大小变动要重置所有组件的位置，重新定位
        # 不需要判断窗口是否移动，因为组件之间记录的是相对主窗口位置，窗口位置变动只需要定位时变更主窗口位置
        logger.debug('检测主窗口位置: %s', self.__win_id)
        ox, oy, ow, oh = self.client_rect
        self.locate()
        x, y, w, h = self.client_rect
        if ow != w or oh != h and ox >= 0:
            logger.debug('主窗口位置变动, 重置子组件')
            for component in self.children:
                component.reset()
        # 定位当前监听列表的组件，对当前窗口显示的组件组件触发显示事件
        show_sources = [x for x in self.__event_manager.sources(EventType.SHOW) if x.locate()]
        self.__event_manager.trigger(EventType.SHOW, show_sources)

    def add_listener(self, event_type, source, listener):
        return self.__event_manager.add_listener(event_type, source, listener)

    def _locate(self):
        rect = gui.get_window_rect(self.__win_id)
        logger.debug('检测到主窗口位置: %s, %s', self.__win_id, rect)
        self.set_location_rect(rect)
        return True


class FrameManager(object):

    def __init__(self):
        self.__frames = []
        self.__scripts = []

    @property
    def frames(self):
        return self.__frames

    def add_frame(self, frame):
        self.__frames.append(frame)
        logger.info('加载窗口: %s', frame.win_id)

    def add_script(self, script):
        self.__scripts.append(script)
        logger.info('加载脚本: %s', script.name)

    def start(self):
        scripts = []
        for x in self.__scripts:
            if x.daemon:
                x.start()
            else:
                scripts.append(x)
        scripts[0].start()
        for frame in self.__frames:
            frame.start()
        for t in self.__frames:
            t.join()

    def close(self):
        for frame in self.__frames:
            frame.destroy()
